package land;

import java.awt.Graphics;
import tools.CollisionGrid;
import abstracts.Level;

public class Land {
    // Variables to cache
    private final Level LEVEL;
    private final CollisionGrid CG;
    private final int WIDTH;
    private final int ROWS;
    private final int COLS;

    public Land(CollisionGrid cg, Level level) {
        LEVEL = level;
        CG = cg;
        WIDTH = level.getWidth();
        ROWS = CG.getRows();
        COLS = CG.getCols();
        renderAll();
    }

    public void renderAll() {
        for (int row = 0; row < ROWS; row++) {
            LandRow landRow = new LandRow(0, row * 32, WIDTH, 48, LEVEL);
            Graphics g = landRow.getGraphics();

            for (int col = 0; col < COLS; col++) {
                int frameIndex = getTop(row, col).getFrameIndex();
                LandTop.sprite.draw(g, frameIndex, col * 32 + 4, 0);
            }

            for (int col = 0; col <= COLS; col++) {
                int frameIndex = getSide(row, col).getFrameIndex();
                LandSide.sprite.draw(g, frameIndex, col * 32 - 4, 0);
            }

            for (int col = 0; col <= COLS; col++) {
                int frameIndex = getFront(row, col).getFrameIndex();
                if (frameIndex >= 0) {
                    LandFront.sprite.draw(g, frameIndex, col * 32 - 16, 32);
                }
            }

            LEVEL.add(landRow);
        }
    }

    public LandTop getTop(int row, int col) {
        if (CG.isWall(row, col)) {
            return LandTop.ROOF;
        } else {
            return LandTop.GROUND;
        }
    }

    public LandSide getSide(int row, int col) {
        // *---*---*
        // | a | b |
        // *---*---*
        boolean a = CG.isWall(row, col - 1);
        boolean b = CG.isWall(row, col);

        if (a) {
            if (b) {
                // T T
                return LandSide.ROOF_TO_ROOF;
            } else {
                // T F
                return LandSide.ROOF_TO_GROUND;
            }
        } else {
            if (b) {
                // F T
                return LandSide.GROUND_TO_ROOF;
            } else {
                // F F
                return LandSide.GROUND_TO_GROUND;
            }
        }
    }

    public LandFront getFront(int row, int col) {
        // *---*---*
        // | a | b |
        // *---*---*
        // | c | d |
        // *---*---*
        boolean a = CG.isWall(row, col - 1);
        boolean b = CG.isWall(row, col);
        boolean c = CG.isWall(row + 1, col - 1);
        boolean d = CG.isWall(row + 1, col);

        // Decision Tree
        if (a) {
            if (b) {
                if (!c) {
                    if (d) {
                        // T T
                        // F T
                        return LandFront.WALL_TO_ROOF;
                    } else {
                        // T T
                        // F F
                        return LandFront.WALL_TO_WALL;
                    }
                } else if (!d) {
                    // T T
                    // T F
                    return LandFront.ROOF_TO_WALL;
                }
            } else if (!c) {
                // T F
                // F ?
                return LandFront.WALL_TO_GROUND;
            }
        } else if (b && !d) {
            // F T
            // ? F
            return LandFront.GROUND_TO_WALL;
        }

        // If no front or front is hidden
        return LandFront.NONE;
    }
}
